"""
发布管理服务
"""
from typing import List, Dict, Any
from datetime import datetime
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
from sqlalchemy.orm import selectinload
from app.models.article import Article, ArticleStatus
from app.services.wechat_service import wechat_service
from app.services.article_service import article_service
from app.schemas.publish import (
    PublishToDraftRequest, PublishToDraftResponse, 
    DraftListResponse, MaterialListResponse, PublishHistoryResponse
)
from app.utils.exceptions import WeChatAPIError, ArticleNotFoundError, DatabaseError
from app.utils.logger import logger
from app.utils.helpers import format_wechat_content, format_wechat_publish_content, insert_images_into_wechat_content


class PublishService:
    """发布管理服务"""
    
    async def publish_to_draft(self, db: AsyncSession, 
                              request: PublishToDraftRequest) -> PublishToDraftResponse:
        """发布文章到微信草稿箱"""
        try:
            # 获取文章信息
            article = await article_service.get_article_by_id(db, request.article_id)
            
            if not article.cover_image_id:
                return PublishToDraftResponse(
                    success=False,
                    message="文章缺少封面图片，无法发布",
                    article_id=request.article_id
                )
            
            # 获取文章的媒体素材
            media_assets = article.media_assets or []
            content_media_ids = [asset.media_id for asset in media_assets if asset.position > 0]
            
            # 将原始内容转换为微信发布格式
            logger.info(f"开始处理文章内容，原始长度: {len(str(article.content))}")
            
            # 先应用微信发布专用格式化
            formatted_content = format_wechat_publish_content(str(article.content))
            
            # 然后插入图片
            if content_media_ids:
                logger.info(f"插入图片到内容中，图片数量: {len(content_media_ids)}")
                
                # 从媒体素材中获取CDN URL
                image_data = []
                for asset in media_assets:
                    if asset.position > 0:  # 内容图片
                        cdn_url = asset.original_url if asset.original_url else asset.media_id
                        image_data.append({
                            "url": cdn_url,
                            "media_id": asset.media_id
                        })
                        logger.info(f"图片数据: media_id={asset.media_id}, url={cdn_url}")
                
                # 使用CDN URL插入图片
                formatted_content = insert_images_into_wechat_content(formatted_content, image_data)
            
            logger.info(f"内容处理完成，最终长度: {len(formatted_content)}")
            
            # 准备发布数据
            # 确保摘要不超过微信限制（120字符）
            summary = str(article.summary or "") if article.summary else ""
            if len(summary) > 120:
                logger.warning(f"文章摘要长度({len(summary)}字符)超过微信限制，将截断")
                summary = summary[:117] + "..."
            
            article_data = wechat_service.format_article_for_draft(
                title=str(article.title),
                content=formatted_content,
                summary=summary,
                cover_media_id=str(article.cover_image_id) if article.cover_image_id else "",
                author=request.author or "",
                content_source_url=request.content_source_url or ""
            )
            
            # 设置其他参数
            article_data.update({
                "show_cover_pic": 1 if request.show_cover_pic else 0,
                "need_open_comment": 1 if request.need_open_comment else 0,
                "only_fans_can_comment": 1 if request.only_fans_can_comment else 0
            })
            
            # 发布到微信草稿箱
            draft_id = await wechat_service.create_draft([article_data])
            
            # 更新文章状态
            await article_service.update_article_status(
                db, request.article_id, ArticleStatus.PUBLISHED, draft_id
            )
            
            logger.info(f"文章发布到草稿箱成功: {article.title} (draft_id: {draft_id})")
            
            return PublishToDraftResponse(
                success=True,
                message="文章已成功发布到微信草稿箱",
                draft_id=draft_id,
                article_id=request.article_id
            )
            
        except ArticleNotFoundError as e:
            return PublishToDraftResponse(
                success=False,
                message=str(e),
                article_id=request.article_id
            )
        except WeChatAPIError as e:
            logger.error(f"发布到微信草稿箱失败: {str(e)}")
            return PublishToDraftResponse(
                success=False,
                message=f"发布失败: {str(e)}",
                article_id=request.article_id
            )
        except Exception as e:
            logger.error(f"发布到草稿箱异常: {str(e)}")
            return PublishToDraftResponse(
                success=False,
                message=f"发布异常: {str(e)}",
                article_id=request.article_id
            )
    
    async def get_draft_list(self, offset: int = 0, count: int = 20) -> DraftListResponse:
        """获取微信草稿列表"""
        try:
            drafts = await wechat_service.get_draft_list(offset, count)
            
            # 转换数据格式
            draft_items = []
            for draft in drafts:
                draft_info = {
                    "media_id": draft.get("media_id", ""),
                    "update_time": datetime.fromtimestamp(draft.get("update_time", 0)),
                    "content": draft.get("content", {})
                }
                draft_items.append(draft_info)
            
            logger.info(f"获取草稿列表成功，共 {len(draft_items)} 条记录")
            
            return DraftListResponse(
                items=draft_items,
                total_count=len(draft_items)
            )
            
        except Exception as e:
            logger.error(f"获取草稿列表失败: {str(e)}")
            raise WeChatAPIError(f"获取草稿列表失败: {e}")
    
    async def get_material_list(self, material_type: str = "image", 
                               offset: int = 0, count: int = 20) -> MaterialListResponse:
        """获取微信素材列表"""
        try:
            materials = await wechat_service.get_material_list(material_type, offset, count)
            
            # 转换数据格式
            material_items = []
            for material in materials:
                material_info = {
                    "media_id": material.get("media_id", ""),
                    "name": material.get("name", ""),
                    "update_time": datetime.fromtimestamp(material.get("update_time", 0)),
                    "url": material.get("url", "")
                }
                material_items.append(material_info)
            
            logger.info(f"获取素材列表成功，类型: {material_type}，共 {len(material_items)} 条记录")
            
            return MaterialListResponse(
                items=material_items,
                total_count=len(material_items),
                item_count=len(material_items)
            )
            
        except Exception as e:
            logger.error(f"获取素材列表失败: {str(e)}")
            raise WeChatAPIError(f"获取素材列表失败: {e}")
    
    async def get_publish_history(self, db: AsyncSession, limit: int = 50) -> List[PublishHistoryResponse]:
        """获取发布历史"""
        try:
            # 查询已发布的文章
            result = await db.execute(
                select(Article)
                .options(selectinload(Article.theme))
                .where(Article.status.in_([ArticleStatus.PUBLISHED, ArticleStatus.FAILED]))
                .order_by(Article.published_at.desc(), Article.generated_at.desc())
                .limit(limit)
            )
            articles = result.scalars().all()
            
            # 转换数据格式
            history_items = []
            for article in articles:
                history_item = PublishHistoryResponse(
                    article_id=str(article.id),
                    title=str(article.title),
                    draft_id=str(article.draft_id) if article.draft_id else None,
                    published_at=article.published_at,
                    status=article.status.value,
                    theme_name=str(article.theme.name) if article.theme else None
                )
                history_items.append(history_item)
            
            logger.info(f"获取发布历史成功，共 {len(history_items)} 条记录")
            return history_items
            
        except Exception as e:
            logger.error(f"获取发布历史失败: {str(e)}")
            raise DatabaseError(f"获取发布历史失败: {e}")
    
    async def delete_draft(self, draft_id: str) -> bool:
        """删除微信草稿"""
        try:
            success = await wechat_service.delete_draft(draft_id)
            
            if success:
                logger.info(f"删除微信草稿成功: {draft_id}")
            else:
                logger.warning(f"删除微信草稿失败: {draft_id}")
            
            return success
            
        except Exception as e:
            logger.error(f"删除微信草稿异常: {str(e)}")
            return False
    
    async def batch_publish_articles(self, db: AsyncSession, 
                                   article_ids: List[str]) -> Dict[str, Any]:
        """批量发布文章到草稿箱"""
        results = {
            "success_count": 0,
            "failed_count": 0,
            "results": []
        }
        
        for article_id in article_ids:
            try:
                request = PublishToDraftRequest(
                    article_id=article_id,
                    author="",
                    content_source_url="",
                    show_cover_pic=True,
                    need_open_comment=False,
                    only_fans_can_comment=False
                )
                response = await self.publish_to_draft(db, request)
                
                if response.success:
                    results["success_count"] += 1
                else:
                    results["failed_count"] += 1
                
                results["results"].append({
                    "article_id": article_id,
                    "success": response.success,
                    "message": response.message,
                    "draft_id": response.draft_id
                })
                
            except Exception as e:
                results["failed_count"] += 1
                results["results"].append({
                    "article_id": article_id,
                    "success": False,
                    "message": f"发布异常: {str(e)}",
                    "draft_id": None
                })
                logger.error(f"批量发布文章 {article_id} 失败: {str(e)}")
        
        logger.info(f"批量发布完成，成功: {results['success_count']}, 失败: {results['failed_count']}")
        return results
    
    async def test_wechat_connection(self) -> Dict[str, Any]:
        """测试微信API连接"""
        try:
            success = await wechat_service.test_connection()
            
            return {
                "success": success,
                "message": "微信API连接正常" if success else "微信API连接失败",
                "timestamp": datetime.now().isoformat()
            }
            
        except Exception as e:
            logger.error(f"测试微信API连接失败: {str(e)}")
            return {
                "success": False,
                "message": f"连接测试失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }


# 全局服务实例
publish_service = PublishService()